﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Data;
using System.Windows;
using System.Windows.Media.Animation;
using System.Management;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using ScwsClient.Common;

namespace ScwsWpfClient
{


    /// <summary>
    /// Interaction logic for WindowMain.xaml
    /// </summary>
    public partial class WindowMain : Window
    {
        public int childThreads;



        public delegate void mmdelegate();



        public delegate void listBoxDelegate(string s);



        public WindowMain()
        {
            FormData data = new FormData();

            InitializeComponent();

            initReasonsComboBox();

            data.Rms = Properties.Settings.Default.rms;

            data.Minutes = Properties.Settings.Default.defaultMins.ToString();

            data.Computer = getComputerName();

            data.Reason = comboBoxReason.SelectedItem.ToString();

            this.DataContext = data;

            FocusManager.SetIsFocusScope(windowMain, true);
            FocusManager.SetFocusedElement(windowMain, textBoxComment);
            Keyboard.Focus(textBoxComputerName);

        }



        private bool validateFields()
        {
            try
            {
                Convert.ToInt16(textBoxMinutes.Text);
                return true;
            }
            catch (Exception ex)
            {
                HandleError(ex);
                return false;
            }
        }



        private void initReasonsComboBox()
        {
            String reasonsConfig = Properties.Settings.Default.MMReasons;

            String[] reasons = reasonsConfig.Split(',');

            comboBoxReason.Items.Clear();

            foreach (String r in reasons)
            {
                comboBoxReason.Items.Add(r);
            }

            comboBoxReason.SelectedIndex = 0;

        }



        private string getComputerName()
        {

            string result = System.Environment.MachineName;

            try
            {

                ManagementScope ms = new ManagementScope("root\\cimv2");

                ObjectQuery query = new ObjectQuery("Select Name, Domain, PartOfDomain from Win32_ComputerSystem");

                ManagementObjectSearcher searcher = new ManagementObjectSearcher(ms, query);

                ManagementObjectCollection results = searcher.Get();

                foreach (ManagementObject o in results)
                {
                    if (o["PartOfDomain"].ToString().ToUpper() == "TRUE")
                    {
                        result += "." + o["Domain"];
                    }
                }
            }
            catch (Exception ex)
            {
                HandleError(ex);
            }

            return result;
        }



        private void HandleError(Exception ex)
        {
            // Configure the message box
            string messageBoxText = ex.Message;
            string caption = "SCWS";
            MessageBoxButton button = MessageBoxButton.OK;
            MessageBoxImage icon = MessageBoxImage.Error;
            MessageBoxResult defaultResult = MessageBoxResult.OK;

            // Show message box, passing the window owner if specified
            MessageBoxResult result;

            result = MessageBox.Show(messageBoxText, caption, button, icon, defaultResult);
            buttonStartComputerMm.Dispatcher.BeginInvoke(
                DispatcherPriority.Normal, new mmdelegate(
                enableButtons));
        }



        private void HandleError(string message, string rms)
        {
            // Configure the message box
            string messageBoxText = message;
            string caption = rms.ToUpper();
            MessageBoxButton button = MessageBoxButton.OK;
            MessageBoxImage icon = MessageBoxImage.Error;
            MessageBoxResult defaultResult = MessageBoxResult.OK;

            // Show message box, passing the window owner if specified
            MessageBoxResult result;
            result = MessageBox.Show(messageBoxText, caption, button, icon, defaultResult);
            buttonStartComputerMm.Dispatcher.BeginInvoke(
                DispatcherPriority.Normal, new mmdelegate(
                enableButtons));
        }



        private string[] splitRmsTextBox(string rmsText)
        {
            char[] splitter = ",".ToCharArray();

            string[] rmsArray = rmsText.Split(splitter,StringSplitOptions.RemoveEmptyEntries);

            for (int i = 0; i <= rmsArray.GetUpperBound(0); i++)
            {
                rmsArray[i].Trim();
            }

            return rmsArray;
        }



        #region Delegate helper functions

        private void disableButtons()
        {
            buttonStartComputerMm.IsEnabled = false;
            buttonStopComputerMm.IsEnabled = false;
            buttonQueryComputerMm.IsEnabled = false;
            buttonStartGroupMm.IsEnabled = false;
            buttonStopGroupMm.IsEnabled = false;
            buttonQueryGroupMm.IsEnabled = false;
            buttonSelectGroup.IsEnabled = false;
        }



        private void enableButtons()
        {
            if (childThreads == 0)
            {
                buttonStartComputerMm.IsEnabled = true;
                buttonStopComputerMm.IsEnabled = true;
                buttonQueryComputerMm.IsEnabled = true;
                buttonStartGroupMm.IsEnabled = true;
                buttonStopGroupMm.IsEnabled = true;
                buttonQueryGroupMm.IsEnabled = true;
                buttonSelectGroup.IsEnabled = true;
            }
        }



        public void displayProgress()
        {
            progressBar1.Visibility = Visibility.Visible;
        }



        private void hideProgress()
        {
            if (childThreads == 0)
                progressBar1.Visibility = Visibility.Hidden;
        }



        private void addGroupToListBox(string s)
        {
            listBoxGroups.Items.Add(s);
        }


        private void incrementThreadcount()
        {
            childThreads++;
        }

        private void decrementThreadcount()
        {
            if (childThreads > 0)
                childThreads--;
        }
        #endregion



        #region Form button handling


        private void buttonStartComputerMm_Click(object sender, RoutedEventArgs e)
        {
            if (!validateFields())
            {
                return;
            }

            foreach (string rms in splitRmsTextBox(textBoxRms.Text))
            {

                WebServices ws = new WebServices();

                ws.rms = rms;
                ws.subject = textBoxComputerName.Text;
                ws.minutes = Convert.ToInt16(textBoxMinutes.Text);
                ws.reason = comboBoxReason.Text;
                ws.comment = textBoxComment.Text;

                Object data = new object();

                data = ws;

                disableButtons();

                Thread job = new Thread(startComputerMm);
                job.Start(data);

            }
            
        }



        private void buttonStopComputerMm_Click(object sender, RoutedEventArgs e)
        {
            foreach (string rms in splitRmsTextBox(textBoxRms.Text))
            {
                WebServices ws = new WebServices();

                ws.rms = rms;
                ws.subject = textBoxComputerName.Text;

                Object data = new object();

                data = ws;

                disableButtons();

                Thread job = new Thread(stopComputerMm);
                job.Start(data);
            }
        }



        private void buttonQueryComputerMm_Click(object sender, RoutedEventArgs e)
        {

            foreach (string rms in splitRmsTextBox(textBoxRms.Text))
            {

                WebServices ws = new WebServices();

                ws.rms = rms;
                ws.subject = textBoxComputerName.Text;
                ws.classname = "Microsoft.Windows.Computer";

                Object data = new object();

                data = ws;

                disableButtons();

                Thread job = new Thread(queryComputerMm);
                job.Start(data);
            }
        }



        private void buttonSelectGroup_Click(object sender, RoutedEventArgs e)
        {
            listBoxGroups.Items.Clear();


            WebServices ws = new WebServices();
            ws.rms = splitRmsTextBox(textBoxRms.Text)[0];
            ws.classname = "System.Group";
            ws.subject = "";

            Object data = new object();

            data = ws;

            disableButtons();

            Thread job = new Thread(queryGroups);
            job.Start(data);

        }



        private void buttonStartGroupMm_Click(object sender, RoutedEventArgs e)
        {

            if (!validateFields())
            {
                return;
            }

            foreach (string rms in splitRmsTextBox(textBoxRms.Text))
            {
                WebServices ws = new WebServices();

                ws.rms = rms;
                ws.subject = textBoxGroupName.Text;
                ws.minutes = Convert.ToInt16(textBoxMinutes.Text);
                ws.reason = comboBoxReason.Text;
                ws.comment = textBoxComment.Text;

                Object data = new object();

                data = ws;

                disableButtons();

                Thread job = new Thread(startGroupMm);
                job.Start(data);
            }

        }



        private void buttonStopGroupMm_Click(object sender, RoutedEventArgs e)
        {

            foreach (string rms in splitRmsTextBox(textBoxRms.Text))
            {
                WebServices ws = new WebServices();

                ws.rms = rms;
                ws.subject = textBoxGroupName.Text;

                Object data = new object();

                data = ws;

                disableButtons();

                Thread job = new Thread(stopGroupMm);
                job.Start(data);
            }
        }



        private void buttonQueryGroupMm_Click(object sender, RoutedEventArgs e)
        {
            foreach (string rms in splitRmsTextBox(textBoxRms.Text))
            {
                WebServices ws = new WebServices();

                ws.rms = rms;
                ws.subject = textBoxGroupName.Text;
                ws.classname = "System.Group";

                Object data = new object();

                data = ws;

                disableButtons();

                Thread job = new Thread(queryGroupMm);
                job.Start(data);
            }
        }


        #endregion



        #region Threaded functions


        private void startComputerMm(object data)
        {
            buttonStartComputerMm.Dispatcher.BeginInvoke(
                        System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(incrementThreadcount));

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                        System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(displayProgress));

            string result;

            WebServices ws = (WebServices)data;

            try
            {
                DataTable dt = ws.MMStartByWindowsComputerName();

            result = "Name: " + dt.Rows[0]["MonitoringObjectDisplayName"] + "\n";
            result += "Id: " + dt.Rows[0]["MonitoringObjectID"] + "\n";
            result += "Result: " + dt.Rows[0]["Result"];

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                     new mmdelegate(hideProgress));

            // Show message box
            MessageBoxResult mbresult;
            mbresult = MessageBox.Show(result, ws.rms.ToUpper(), MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
            }
            catch (Exception ex)
            {
                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));
                
                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                            new mmdelegate(hideProgress));

                HandleError(ex.Message, ws.rms);
            }

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(enableButtons));
        }



        private void startGroupMm(object data)
        {
            buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(incrementThreadcount));

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                        System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(displayProgress));

            string result;

            WebServices ws = (WebServices)data;

            try
            {
                DataTable dt = ws.MMStartByGroupName();

                result = "Name: " + dt.Rows[0]["MonitoringObjectDisplayName"] + "\n";
                result += "Id: " + dt.Rows[0]["MonitoringObjectID"] + "\n";
                result += "Result: " + dt.Rows[0]["Result"];

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                         new mmdelegate(hideProgress));

                // Show message box
                MessageBoxResult mbresult;
                mbresult = MessageBox.Show(result, ws.rms.ToUpper(), MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
            }
            catch (Exception ex)
            {
                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                            new mmdelegate(hideProgress));

                HandleError(ex.Message, ws.rms);
            }

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(enableButtons));
        }



        private void stopGroupMm(object data)
        {

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(incrementThreadcount));

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                        System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(displayProgress));

            WebServices ws = (WebServices)data;

            string result;

            try
            {
                DataTable dt = ws.MMStopByGroupName();

                result = "Name: " + dt.Rows[0]["MonitoringObjectDisplayName"] + "\n";
                result += "Id: " + dt.Rows[0]["MonitoringObjectID"] + "\n";
                result += "Result: " + dt.Rows[0]["Result"];

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                       System.Windows.Threading.DispatcherPriority.Normal,
                                new mmdelegate(hideProgress));

                // Show message box
                MessageBoxResult mbresult;
                mbresult = MessageBox.Show(result, ws.rms.ToUpper(), MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
            }
            catch (Exception ex)
            {
                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                            new mmdelegate(hideProgress));

                HandleError(ex.Message, ws.rms);
            }

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(enableButtons));

        }



        private void queryGroupMm(object data)
        {
            buttonStartComputerMm.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                new mmdelegate(incrementThreadcount));

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                        System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(displayProgress));
            
            WebServices ws = (WebServices)data;

            try
            {
                ws.id = ws.GetMonitoringObjectId();

                DataTable dt = ws.GetMonitoringObjectInfo();

                string result = "Name: " + dt.Rows[0]["DisplayName"] + "\n";
                result += "Id: " + dt.Rows[0]["Id"] + "\n";
                result += "Healthstate: " + dt.Rows[0]["HealthState"] + "\n";
                result += "In Maintenance Mode: " + dt.Rows[0]["InMaintenanceMode"] + "\n";

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                            new mmdelegate(hideProgress));

                // Show message box
                MessageBoxResult mbresult;
                mbresult = MessageBox.Show(result, ws.rms.ToUpper(), MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);

            }
            catch (Exception ex)
            {
                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                            new mmdelegate(hideProgress));

                HandleError(ex.Message, ws.rms);
            }

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(enableButtons));
        }



        private void stopComputerMm(object data)
        {
            buttonStartComputerMm.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                new mmdelegate(incrementThreadcount));

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                        System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(displayProgress));
            
            WebServices ws = (WebServices)data;

            string result;

            try
            {
                DataTable dt = ws.MMStopByWindowsComputerName();

                result = "Name: " + dt.Rows[0]["MonitoringObjectDisplayName"] + "\n";
                result += "Id: " + dt.Rows[0]["MonitoringObjectID"] + "\n";
                result += "Result: " + dt.Rows[0]["Result"];
                
                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                       System.Windows.Threading.DispatcherPriority.Normal,
                                new mmdelegate(hideProgress));

                // Show message box
                MessageBoxResult mbresult;
                mbresult = MessageBox.Show(result, ws.rms.ToUpper(), MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
            }
            catch (Exception ex)
            {
                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                            new mmdelegate(hideProgress));

                HandleError(ex.Message, ws.rms);
            }

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(enableButtons));
        }



        private void queryComputerMm(object data)
        {

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                new mmdelegate(incrementThreadcount));
            
            buttonStartComputerMm.Dispatcher.BeginInvoke(
                        System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(displayProgress));
            
            WebServices ws = (WebServices)data;

            try
            {
                ws.id = ws.GetMonitoringObjectId();

                DataTable dt = ws.GetMonitoringObjectInfo();

                string result = "Name: " + dt.Rows[0]["DisplayName"] + "\n";
                result += "Id: " + dt.Rows[0]["Id"] + "\n";
                result += "Healthstate: " + dt.Rows[0]["HealthState"] + "\n";
                result += "In Maintenance Mode: " + dt.Rows[0]["InMaintenanceMode"] + "\n";

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                            new mmdelegate(hideProgress));

                // Show message box
                MessageBoxResult mbresult;
                mbresult = MessageBox.Show(result, ws.rms.ToUpper(), MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);

            }
            catch (Exception ex)
            {
                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                            new mmdelegate(hideProgress));

                HandleError(ex.Message, ws.rms);
            }

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                        new mmdelegate(enableButtons));

        }



        private void queryGroups(object data)
        {
            
            buttonStartComputerMm.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                new mmdelegate(incrementThreadcount));

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(displayProgress));
            
            WebServices ws = (WebServices)data;

            try
            {
                DataTable dt = ws.QueryMonitoringObjectsByClassName();

                foreach (DataRow  row in dt.Rows)
                {
                    string name = row["DisplayName"].ToString();
                    buttonStartComputerMm.Dispatcher.BeginInvoke(
                        System.Windows.Threading.DispatcherPriority.Normal,
                                new listBoxDelegate(addGroupToListBox),
                                name);
                }


                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                            new mmdelegate(delegate()
                {
                    listBoxGroups.Visibility = Visibility.Visible;
                }));


                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                            new mmdelegate(delegate()
                {
                listBoxGroups.Items.SortDescriptions.Add(new System.ComponentModel.SortDescription());
                }));

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));
                
                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                            new mmdelegate(hideProgress));
            }
            catch (Exception ex)
            {
                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new mmdelegate(decrementThreadcount));

                buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                            new mmdelegate(hideProgress));

                HandleError(ex.Message, ws.rms);
            }

            buttonStartComputerMm.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                         new mmdelegate(enableButtons));

        }

        #endregion



        #region Form manipulation


        private void button1HourMm_Click(object sender, RoutedEventArgs e)
        {
            textBoxMinutes.Text = "60";
        }



        private void button1DayMm_Click(object sender, RoutedEventArgs e)
        {
            textBoxMinutes.Text = "1440";
        }



        private void button7DayMm_Click(object sender, RoutedEventArgs e)
        {
            textBoxMinutes.Text = "10080";
        }



        private void button12HourMm_Click(object sender, RoutedEventArgs e)
        {
            textBoxMinutes.Text = "720";
        }



        private void button6HourMm_Click(object sender, RoutedEventArgs e)
        {
            textBoxMinutes.Text = "360";
        }



        private void listBoxGroups_MouseDoubleClick(object sender, RoutedEventArgs e)
        {
            textBoxGroupName.Text = listBoxGroups.SelectedItem.ToString();
            listBoxGroups.Visibility = Visibility.Hidden;
            enableButtons();
        }



        private void listBoxGroups_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                textBoxGroupName.Text = listBoxGroups.SelectedItem.ToString();
                listBoxGroups.Visibility = Visibility.Hidden;
                enableButtons();
            }
        }

        #endregion
    }

}
